package com.cg.design.depthdesign.singleton;

/**
 * 创建型模式：Singleton单例模式测试类
 * <p>
 * 单例模式是一种创建型设计模式，让你能够保证一个类只有一个实例， 并提供一个访问该实例的全局节点。
 *
 * @author cg
 * @program LeetCode->SingletonTest
 * @create 2022-07-18 21:57
 **/
public class SingletonTest {

    public static void main(String[] args) {
        // 测试基础单例（单线程）
        System.out.println("If you see the same value, then singleton was reused (yay!)" + "\n" +
                "If you see different values, then 2 singletons were created (booo!!)" + "\n\n" +
                "RESULT:" + "\n");
        Singleton singleton = Singleton.getInstance("FOO");
        Singleton anotherSingleton = Singleton.getInstance("BAR");
        System.out.println(singleton.value);
        System.out.println(anotherSingleton.value);

        // 测试基础单例（多线程）
        System.out.println("If you see the same value, then singleton was reused (yay!)" + "\n" +
                "If you see different values, then 2 singletons were created (booo!!)" + "\n\n" +
                "RESULT:" + "\n");
        Thread threadTea = new Thread(new ThreadFoo());
        Thread threadCoco = new Thread(new ThreadBar());
        threadTea.start();
        threadCoco.start();

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 测试采用延迟加载的线程安全单例
        System.out.println("If you see the same value, then singleton was reused (yay!)" + "\n" +
                "If you see different values, then 2 singletons were created (booo!!)" + "\n\n" +
                "RESULT:" + "\n");
        threadTea = new Thread(new ThreadTea());
        threadCoco = new Thread(new ThreadCoco());
        threadTea.start();
        threadCoco.start();
    }

    static class ThreadFoo implements Runnable {
        @Override
        public void run() {
            MultiSingleton singleton = MultiSingleton.getInstance("FOO");
            System.out.println(singleton.value);
        }
    }

    static class ThreadBar implements Runnable {
        @Override
        public void run() {
            MultiSingleton singleton = MultiSingleton.getInstance("BAR");
            System.out.println(singleton.value);
        }
    }

    static class ThreadTea implements Runnable {
        @Override
        public void run() {
            MultiLazySingleton singleton = MultiLazySingleton.getInstance("Tea");
            System.out.println(singleton.value);
        }
    }

    static class ThreadCoco implements Runnable {
        @Override
        public void run() {
            MultiLazySingleton singleton = MultiLazySingleton.getInstance("BAR");
            System.out.println(singleton.value);
        }
    }

}
